<?php
/**
 * author: yunshu
 * create: 18/2/28
 * description:
 */

namespace app\common\service;

use app\common\service\Token as TokenService;
use app\common\model\Order as OrderModel;
use app\common\service\Order as OrderService;
use app\library\enum\OrderStatus;
use app\library\exception\OrderException;
use app\library\exception\TokenException;
use think\Exception;
use think\facade\Env;
use think\facade\Log;

require_once Env::get('root_path') . 'extend/wxpay/WxPay.Api.php';

class Pay extends Base
{
    protected $orderId;
    protected $orderNo;

    public function __construct($orderId)
    {
        if (! $orderId) {
            throw new Exception("orderid不存在");
        }

        $this->orderId = $orderId;
    }
    
    public function preOrder()
    {
        //检查订单是否有效
        $this->checkOrderValid();

        //检查库存
        $status = (new OrderService())->checkOrderStock($this->orderId);
        if (! $status['pass']) {
            return $status;
        }

        //创建微信预支付交易信息
        return $this->makePreOrder($status['orderPrice']);
    }

    public function checkOrderValid()
    {
        //检查订单是否存在
        $order = OrderModel::where('id', '=', $this->orderId)->find();
        if (! $order) {
            throw new OrderException();
        }

        //检查是否是该用户的订单
        $valid = TokenService::isValidOperate($order->user_id);
        if (! $valid) {
            throw new TokenException(EC_ILLEGAL_OPERATION, '非法操作');
        }

        //查看订单是否支付
        if ($order->status != OrderStatus::UN_PAID) {
            throw new OrderException(EC_ALREADY_PAID, '订单已支付', 400);
        }

        $this->orderNo = $order->order_no;

        return true;
    }

    public function makePreOrder($totalPrice)
    {
        $openId = TokenService::getCurrentTokenVar('openid');

        $wxPayUnifiedOrder = new \WxPayUnifiedOrder();
        $wxPayUnifiedOrder->SetOut_trade_no($this->orderNo);
        $wxPayUnifiedOrder->SetBody('小商城');
        $wxPayUnifiedOrder->SetTotal_fee((string)$totalPrice*100);
        $wxPayUnifiedOrder->SetTrade_type('JSAPI');
        $wxPayUnifiedOrder->SetOpenid($openId);

        return $this->getPaySignature($wxPayUnifiedOrder);
    }

    //获取支付数据签名
    public function getPaySignature($wxPayUnifiedOrder)
    {
        //生成预支付交易单
        $prepayOrder = \WxPayApi::unifiedOrder($wxPayUnifiedOrder);
        if ($prepayOrder['return_code'] != 'SUCCESS' || $prepayOrder['result_code'] != 'SUCCESS') {
            Log::error($prepayOrder);
            throw new Exception($prepayOrder['return_msg']);
        }

        $this->recordPrepayOrder($prepayOrder);

        return $this->sign($prepayOrder);
    }

    public function recordPrepayId($prepayOrder)
    {
        OrderModel::where('id', '=', $this->orderId)->update(['prepay_id'=>$prepayOrder['prepay_id']]);
    }

    public function sign($prepayOrder)
    {
        $jsApiPayData = new \WxPayJsApiPay();
//        $jsApiPayData->SetAppid($prepayOrder['appid']);
        $rand = md5(time().microtime().mt_rand(0, 1000));
        $jsApiPayData->SetNonceStr($rand);
        $jsApiPayData->SetPackage('prepay_id='.$prepayOrder['prepay_id']);
        $jsApiPayData->SetSignType('MD5');
        $jsApiPayData->SetTimeStamp((string)time());
        $paySign = $jsApiPayData->MakeSign();
        $values = $jsApiPayData->GetValues();
        $values['paySign'] = $paySign;

        return $values;
    }
}